/*
 * GraphQL内容项类型构建器 - ContentItemTypeBuilder
 * 
 * 主要功能：
 * - 扩展ContentItem类型字段的GraphQL功能
 * - 为内容项类型添加自定义参数和过滤器
 * - 支持内容项的动态查询扩展
 * - 提供统一的GraphQL类型构建机制
 */

using GraphQL.Types;
using OrchardCore.ContentManagement.GraphQL.Queries.Types;
using OrchardCore.ContentManagement.Metadata.Models;
using System.Linq;

namespace Lombiq.TrainingDemo.GraphQL.Services;

/// <summary>
/// 内容项类型构建器 - 扩展ContentItem类型字段的GraphQL功能
/// 
/// 主要用途：
/// - 扩展ContentItem类型字段的GraphQL功能
 //* - 为内容项类型添加自定义参数和过滤器
 //* - 支持内容项的动态查询扩展
 //* - 提供统一的GraphQL类型构建机制
 //* 
 //* 使用场景：
/// - 为内容项类型添加年龄过滤参数
/// - 支持多种关系运算符的过滤
/// - 动态扩展内容项的GraphQL查询能力
/// - 实现模块化的GraphQL类型扩展
/// 
/// 设计原因：
/// - 提供灵活的内容项查询扩展
/// - 支持自定义参数和过滤器的注入
/// - 实现内容项类型的统一扩展机制
/// - 简化GraphQL类型的扩展开发
/// 
/// 设计模式：
/// - 构建器模式：实现IContentTypeBuilder接口
/// - 参数注入模式：动态添加查询参数
/// - 过滤器模式：支持多种关系运算符
/// - 常量模式：统一管理参数名称
/// </summary>
// 实现IContentTypeBuilder接口的服务扩展了现有ContentItem类型字段的功能，包括Orchard Core为每个内容类型自动创建的顶级字段。
// 您可以使用它为现有ContentItem类型字段添加新的子字段或过滤属性。
public class ContentItemTypeBuilder : IContentTypeBuilder
{
    /// <summary>
    /// 年龄过滤参数名称常量
    /// 
    /// 功能说明：
    /// - 统一管理年龄过滤参数名称
    /// - 便于在IGraphQLFilter中复用
    /// </summary>
    public const string AgeFilterName = "age";

    /// <summary>
    /// 构建方法 - 为每个内容类型（顶级）字段添加参数
    /// 
    /// 功能说明：
    /// - 检查内容项类型是否包含person子字段
    /// - 为内容项类型添加年龄相关的过滤参数
    /// - 支持多种关系运算符（等于、小于、小于等于、大于、大于等于、不等于）
    /// - 动态扩展内容项的GraphQL查询能力
    /// 
    /// 参数说明：
    /// - schema：GraphQL schema对象
    /// - contentQuery：内容查询字段
    /// - contentTypeDefinition：内容类型定义
    /// - contentItemType：内容项类型
    /// </summary>
    public void Build(
        ISchema schema,
        FieldType contentQuery,
        ContentTypeDefinition contentTypeDefinition,
        ContentItemType contentItemType)
    {
        // 您可以检查字段是否具有特定的子字段，如果您想依赖其功能。例如，如果您只想应用于具有"person"子字段的ContentItem字段（即具有PersonPart的内容项）。
        // 这在您想在另一个模块中扩展内容部件字段时很有用。
        if (contentItemType.Fields.All(field => field.Name != "person")) return;

        // 解析类型可以是任何可以用JSON表示并具有已知图类型的类型，但为简单起见我们坚持使用数字。这个过滤器用于等式。
        AddFilter(contentQuery, suffix: string.Empty);

        // 按GraphQL约定，参数名称不能使用特殊字符，这些两字母后缀表示关系运算符。除了等式通常没有后缀。
        AddFilter(contentQuery, "_lt");
        AddFilter(contentQuery, "_le");

        AddFilter(contentQuery, "_ge");
        AddFilter(contentQuery, "_gt");

        AddFilter(contentQuery, "_ne");
    }

    /// <summary>
    /// 添加过滤参数方法 - 为内容查询字段添加指定后缀的年龄过滤参数
    /// 
    /// 功能说明：
    /// - 动态添加年龄过滤参数
    /// - 支持多种关系运算符
    /// - 设置参数类型为IntGraphType
    /// </summary>
    /// <param name="contentQuery">内容查询字段</param>
    /// <param name="suffix">参数后缀（如_lt、_le等）</param>
    private static void AddFilter(FieldType contentQuery, string suffix)
    {
        contentQuery.Arguments ??= [];
        contentQuery.Arguments!.Add(new QueryArgument<IntGraphType>
        {
            Name = AgeFilterName + suffix,
            ResolvedType = new IntGraphType(),
        });
    }
}

// 下一站：Services/PersonAgeGraphQLFilter.cs
